"""
格式规范专家代理 - 负责检查文本体例、格式的规范性
"""

from typing import Dict, List, Any, Optional
import time
import re
from loguru import logger

from .base_agent import BaseAgent, AgentResult, ReviewItem
from ..utils.data_loader import ProcessingElement


class FormatAgent(BaseAgent):
    """格式规范专家代理"""
    
    def __init__(self, api_client, config: Dict[str, Any]):
        super().__init__(
            name="格式规范专家",
            agent_type="format_review",
            api_client=api_client,
            config=config
        )
    
    def get_system_prompt(self) -> str:
        """获取系统提示词"""
        return """你是城市更新方案册文本格式规范审查专家，负责检查文档的体例和格式规范性。

审查重点：
- 整体结构：目录完整性、章节层级清晰度、内容完整性
- 文字格式：字体统一性、字号规范性、行距段落、对齐方式
- 标题层级：标题编号规范（1、1.1、1.1.1）、层级逻辑清晰
- 引用注释：引用格式规范、注释标注清晰
- 语言表达：简洁准确、专业术语规范、语法标点正确

评分标准（总分100分）：
1. 结构规范性（25分）：目录完整性、章节层级、内容组织
2. 文字格式（25分）：字体统一、字号规范、行距段落、对齐方式
3. 标题层级（20分）：编号规范、层级逻辑、格式一致性
4. 引用格式（15分）：引用规范、注释标注、参考文献格式
5. 语言表达（15分）：语法正确、术语规范、表达清晰

扣分规则：
- critical问题：每项扣5分
- major问题：每项扣3分  
- minor问题：每项扣1分

置信度计算：基于检查覆盖度、问题识别准确性、格式标准掌握程度

输出JSON格式：
{
    "findings": [
        {
            "item_id": "format_001",
            "category": "格式规范",
            "severity": "critical/major/minor/info",
            "description": "具体问题描述",
            "suggestion": "改进建议",
            "format_type": "格式类型",
            "location": "问题位置",
            "confidence": 0.9,
            "score_impact": -3,
            "check_item": "结构规范性"
        }
    ],
    "summary": "格式规范整体评估摘要",
    "scoring_details": {
        "structure_score": 20,
        "text_format_score": 22,
        "title_hierarchy_score": 18,
        "reference_format_score": 13,
        "language_expression_score": 14,
        "total_score": 87,
        "deduction_details": "扣分详情说明"
    }
}

严重性等级：critical(严重格式错误)、major(重要格式问题)、minor(轻微格式问题)、info(优化建议)"""
    
    def process(self, data: Any, context: Dict[str, Any] = None) -> AgentResult:
        """处理数据并返回格式规范审查结果"""
        start_time = time.time()
        
        if not self.validate_input(data):
            return self.handle_api_error(
                Exception("输入数据无效"), 
                "格式规范审查"
            )
        
        try:
            # 提取文本数据
            text_data = self._extract_text_data(data)
            
            if not text_data:
                return self.create_result(
                    success=True,
                    findings=[],
                    summary="无文本内容需要审查格式",
                    confidence=1.0,
                    processing_time=time.time() - start_time
                )
            
            self.log_processing_start(f"格式规范审查，文本段落数量: {len(text_data)}")
            
            # 进行格式检查
            all_review_items = []
            format_analysis = {
                "structure_score": 0,
                "text_format_score": 0,
                "table_format_score": 0,
                "overall_score": 0
            }
            
            # 1. 结构规范性检查
            structure_items = self._check_structure_format(text_data)
            all_review_items.extend(structure_items)
            
            # 2. 文字格式检查
            text_format_items = self._check_text_format(text_data)
            all_review_items.extend(text_format_items)
            
            # 3. 标题层级检查
            title_items = self._check_title_hierarchy(text_data)
            all_review_items.extend(title_items)
            
            # 4. 引用格式检查
            reference_items = self._check_reference_format(text_data)
            all_review_items.extend(reference_items)
            
            # 5. 使用LLM进行深度格式分析
            llm_items = self._llm_format_analysis(text_data, context)
            all_review_items.extend(llm_items)
            
            # 计算格式评分
            format_analysis = self._calculate_format_scores(all_review_items)
            
            # 生成结果
            processing_time = time.time() - start_time
            findings = self.format_findings(all_review_items)
            summary = self.generate_summary(all_review_items)
            confidence = self.calculate_confidence(all_review_items)
            
            self.log_processing_end(True, processing_time, len(findings))
            
            return self.create_result(
                success=True,
                findings=findings,
                summary=summary,
                confidence=confidence,
                processing_time=processing_time,
                metadata={
                    "total_text_segments": len(text_data),
                    "format_analysis": format_analysis,
                    "agent_type": self.agent_type
                }
            )
            
        except Exception as e:
            return self.handle_api_error(e, "格式规范审查")
    
    def _extract_text_data(self, data: Any) -> List[Dict[str, Any]]:
        """提取文本数据"""
        text_data = []
        
        if isinstance(data, list):
            for item in data:
                if isinstance(item, ProcessingElement):
                    # 检查是否为文本类型 - 修复：检查category和metadata字段
                    if (hasattr(item, 'category') and item.category in ['text', 'title', 'paragraph', 'heading']) or \
                       (hasattr(item, 'subcategory') and item.subcategory in ['text', 'title', 'paragraph', 'heading']) or \
                       (hasattr(item, 'source_type') and item.source_type == 'text') or \
                       (hasattr(item, 'metadata') and item.metadata and 
                        item.metadata.get('element_type') in ['Text', 'Title', 'Paragraph', 'Heading']) or \
                       (hasattr(item, 'content') and item.content and isinstance(item.content, str) and len(item.content.strip()) > 0):
                        text_data.append({
                            'content': item.content,
                            'element_id': item.element_id,
                            'category': item.category,
                            'subcategory': item.subcategory,
                            'metadata': item.metadata
                        })
                elif isinstance(item, dict):
                    # 检查字典格式的数据 - 修复：检查category和metadata字段
                    if (item.get('category') in ['text', 'title', 'paragraph', 'heading']) or \
                       (item.get('subcategory') in ['text', 'title', 'paragraph', 'heading']) or \
                       (item.get('source_type') == 'text') or \
                       (item.get('metadata', {}).get('element_type') in ['Text', 'Title', 'Paragraph', 'Heading']) or \
                       (item.get('content') and isinstance(item.get('content'), str) and len(item.get('content', '').strip()) > 0):
                        text_data.append(item)
        elif isinstance(data, ProcessingElement):
            # 单个ProcessingElement对象
            if (hasattr(data, 'category') and data.category in ['text', 'title', 'paragraph', 'heading']) or \
               (hasattr(data, 'subcategory') and data.subcategory in ['text', 'title', 'paragraph', 'heading']) or \
               (hasattr(data, 'source_type') and data.source_type == 'text') or \
               (hasattr(data, 'metadata') and data.metadata and 
                data.metadata.get('element_type') in ['Text', 'Title', 'Paragraph', 'Heading']) or \
               (hasattr(data, 'content') and data.content and isinstance(data.content, str) and len(data.content.strip()) > 0):
                text_data.append({
                    'content': data.content,
                    'element_id': data.element_id,
                    'category': data.category,
                    'subcategory': data.subcategory,
                    'metadata': data.metadata
                })
        elif isinstance(data, dict):
            # 单个字典对象
            if (data.get('category') in ['text', 'title', 'paragraph', 'heading']) or \
               (data.get('subcategory') in ['text', 'title', 'paragraph', 'heading']) or \
               (data.get('source_type') == 'text') or \
               (data.get('metadata', {}).get('element_type') in ['Text', 'Title', 'Paragraph', 'Heading']) or \
               (data.get('content') and isinstance(data.get('content'), str) and len(data.get('content', '').strip()) > 0):
                text_data.append(data)
        
        return text_data
    
    def _check_structure_format(self, text_data: List[Dict[str, Any]]) -> List[ReviewItem]:
        """检查结构格式"""
        review_items = []
        
        # 检查是否有目录结构
        has_toc = False
        title_levels = []
        
        for item in text_data:
            content = item.get('content', '')
            category = item.get('category', '')
            
            # 检查目录
            if '目录' in content or 'contents' in content.lower():
                has_toc = True
            
            # 检查标题层级
            if category == 'title' or '标题' in str(item.get('subcategory', '')):
                level = self._detect_title_level(content)
                if level:
                    title_levels.append(level)
        
        # 评估结构完整性
        if not has_toc:
            review_items.append(self.create_review_item(
                item_id="format_no_toc",
                category="结构格式",
                severity="major",
                description="未发现目录结构",
                suggestion="建议添加完整的目录，包含章节标题和页码"
            ))
        
        # 检查标题层级的连续性
        if title_levels:
            level_gaps = self._check_title_level_gaps(title_levels)
            if level_gaps:
                review_items.append(self.create_review_item(
                    item_id="format_title_gaps",
                    category="结构格式",
                    severity="minor",
                    description=f"标题层级存在跳跃: {level_gaps}",
                    suggestion="建议保持标题层级的连续性，避免跳级"
                ))
        
        return review_items
    
    def _check_text_format(self, text_data: List[Dict[str, Any]]) -> List[ReviewItem]:
        """检查文字格式"""
        review_items = []
        
        # 检查常见格式问题
        for i, item in enumerate(text_data):
            content = item.get('content', '')
            element_id = item.get('element_id', f'text_{i}')
            
            # 检查空行过多
            if content.count('\n\n\n') > 0:
                review_items.append(self.create_review_item(
                    item_id=f"format_excess_lines_{element_id}",
                    category="文字格式",
                    severity="minor",
                    description="存在过多空行",
                    suggestion="建议规范段落间距，避免连续多个空行"
                ))
            
            # 检查标点符号使用
            punctuation_issues = self._check_punctuation(content)
            if punctuation_issues:
                review_items.append(self.create_review_item(
                    item_id=f"format_punctuation_{element_id}",
                    category="文字格式",
                    severity="minor",
                    description=f"标点符号使用不规范: {punctuation_issues}",
                    suggestion="建议规范标点符号的使用，遵循中文标点规范"
                ))
            
            # 检查数字和单位格式
            number_issues = self._check_number_format(content)
            if number_issues:
                review_items.append(self.create_review_item(
                    item_id=f"format_numbers_{element_id}",
                    category="文字格式",
                    severity="minor",
                    description=f"数字格式不规范: {number_issues}",
                    suggestion="建议统一数字和单位的表示格式"
                ))
        
        return review_items
    
    def _check_title_hierarchy(self, text_data: List[Dict[str, Any]]) -> List[ReviewItem]:
        """检查标题层级"""
        review_items = []
        title_items = []
        
        # 收集所有标题
        for item in text_data:
            category = item.get('category', '')
            subcategory = item.get('subcategory', '')
            content = item.get('content', '')
            
            if category == 'title' or '标题' in str(subcategory):
                title_items.append({
                    'content': content,
                    'element_id': item.get('element_id', ''),
                    'level': self._detect_title_level(content)
                })
        
        # 检查标题编号规范性
        for title in title_items:
            content = title['content']
            level = title['level']
            element_id = title['element_id']
            
            # 检查标题编号格式
            if level and not self._is_valid_title_numbering(content, level):
                review_items.append(self.create_review_item(
                    item_id=f"format_title_numbering_{element_id}",
                    category="标题格式",
                    severity="minor",
                    description=f"标题编号格式不规范: {content[:50]}...",
                    suggestion="建议使用规范的标题编号格式（如1、1.1、1.1.1）"
                ))
        
        return review_items
    
    def _check_reference_format(self, text_data: List[Dict[str, Any]]) -> List[ReviewItem]:
        """检查引用格式"""
        review_items = []
        
        for i, item in enumerate(text_data):
            content = item.get('content', '')
            element_id = item.get('element_id', f'text_{i}')
            
            # 检查引用格式
            references = re.findall(r'[\[【].*?[\]】]', content)
            for ref in references:
                if not self._is_valid_reference_format(ref):
                    review_items.append(self.create_review_item(
                        item_id=f"format_reference_{element_id}",
                        category="引用格式",
                        severity="minor",
                        description=f"引用格式不规范: {ref}",
                        suggestion="建议使用规范的引用格式，包含完整的来源信息"
                    ))
        
        return review_items
    
    def _llm_format_analysis(self, text_data: List[Dict[str, Any]], context: Dict[str, Any] = None) -> List[ReviewItem]:
        """使用LLM进行深度格式分析"""
        try:
            # 构建格式分析提示
            prompt = self._build_format_analysis_prompt(text_data, context)
            
            # 调用LLM
            response = self.api_client.chat_completion(
                messages=[
                    {"role": "system", "content": self.get_system_prompt()},
                    {"role": "user", "content": prompt}
                ],
                model=self.config.get('text_model', 'Qwen2.5-7B-Instruct')
            )
            
            # 解析响应
            return self.parse_llm_response(response)
            
        except Exception as e:
            logger.error(f"LLM格式分析失败: {e}")
            return [self.create_review_item(
                item_id="format_llm_error",
                category="分析错误",
                severity="info",
                description=f"LLM格式分析失败: {str(e)}",
                suggestion="请检查文本内容或重新分析"
            )]
    
    def _build_format_analysis_prompt(self, text_data: List[Dict[str, Any]], context: Dict[str, Any] = None) -> str:
        """构建格式分析提示"""
        prompt_parts = [
            "对以下城市更新方案册的文本内容进行格式规范性审查：",
            "",
            "=== 文本内容摘要 ===",
            f"文本段落数量: {len(text_data)}",
        ]
        
        # 添加文本内容示例
        for i, item in enumerate(text_data[:5]):  # 只显示前5个
            content = item.get('content', '')[:200]  # 截取前200字符
            category = item.get('category', '未知')
            prompt_parts.extend([
                f"",
                f"段落 {i+1} ({category}):",
                f"{content}..."
            ])
        
        if len(text_data) > 5:
            prompt_parts.append(f"... (共{len(text_data)}个文本段落)")
        
        prompt_parts.extend([
            "",
            "=== 重点审查内容 ===",
            "1. 整体结构：目录完整性、层次分明、内容完整",
            "2. 文字格式：字体统一、字号规范、行距段落、对齐方式",
            "3. 标题格式：编号规范、层级清晰、格式统一",
            "4. 引用格式：引用规范、注释清晰、来源标注",
            "5. 语言表达：简洁明了、专业术语、语法标点",
            "6. 数据格式：单位统一、数字规范、表格格式",
            "",
            "按照系统提示中的JSON格式输出详细的格式审查结果。"
        ])
        
        return "\n".join(prompt_parts)
    
    def _detect_title_level(self, content: str) -> Optional[int]:
        """检测标题层级"""
        # 检测数字编号格式
        patterns = [
            r'^(\d+)\.?\s',  # 1. 或 1 
            r'^(\d+)\.(\d+)\.?\s',  # 1.1. 或 1.1
            r'^(\d+)\.(\d+)\.(\d+)\.?\s',  # 1.1.1. 或 1.1.1
            r'^(\d+)\.(\d+)\.(\d+)\.(\d+)\.?\s',  # 1.1.1.1
        ]
        
        for i, pattern in enumerate(patterns, 1):
            if re.match(pattern, content.strip()):
                return i
        
        # 检测中文编号格式
        chinese_patterns = [
            r'^[一二三四五六七八九十]+[、．]\s',  # 一、二、三
            r'^（[一二三四五六七八九十]+）\s',  # （一）（二）
        ]
        
        for pattern in chinese_patterns:
            if re.match(pattern, content.strip()):
                return 1
        
        return None
    
    def _check_title_level_gaps(self, levels: List[int]) -> str:
        """检查标题层级跳跃"""
        gaps = []
        for i in range(1, len(levels)):
            if levels[i] - levels[i-1] > 1:
                gaps.append(f"从{levels[i-1]}级跳到{levels[i]}级")
        
        return "; ".join(gaps) if gaps else ""
    
    def _is_valid_title_numbering(self, content: str, level: int) -> bool:
        """检查标题编号是否规范"""
        # 简单的编号格式检查
        if level == 1:
            return bool(re.match(r'^\d+[\.、]\s', content.strip()))
        elif level == 2:
            return bool(re.match(r'^\d+\.\d+[\.、]?\s', content.strip()))
        elif level == 3:
            return bool(re.match(r'^\d+\.\d+\.\d+[\.、]?\s', content.strip()))
        
        return True
    
    def _check_punctuation(self, content: str) -> str:
        """检查标点符号使用"""
        issues = []
        
        # 检查常见标点问题
        if '。。' in content:
            issues.append("连续句号")
        if '，，' in content:
            issues.append("连续逗号")
        if re.search(r'[a-zA-Z][，。]', content):
            issues.append("英文后使用中文标点")
        if re.search(r'[，。][a-zA-Z]', content):
            issues.append("中文标点后直接跟英文")
        
        return "; ".join(issues)
    
    def _check_number_format(self, content: str) -> str:
        """检查数字格式"""
        issues = []
        
        # 检查数字和单位之间的空格
        if re.search(r'\d+[a-zA-Z]', content):
            issues.append("数字和英文单位之间缺少空格")
        if re.search(r'\d+ {2,}[a-zA-Z]', content):
            issues.append("数字和单位之间空格过多")
        
        return "; ".join(issues)
    
    def _is_valid_reference_format(self, reference: str) -> bool:
        """检查引用格式是否规范"""
        # 简单的引用格式检查
        # 应该包含作者、标题、时间等信息
        return len(reference) > 10 and (',' in reference or '，' in reference)
    
    def _calculate_format_scores(self, review_items: List[ReviewItem]) -> Dict[str, int]:
        """计算格式评分"""
        # 基于问题数量和严重性计算评分
        critical_count = sum(1 for item in review_items if item.severity == 'critical')
        major_count = sum(1 for item in review_items if item.severity == 'major')
        minor_count = sum(1 for item in review_items if item.severity == 'minor')
        
        # 计算扣分
        deduction = critical_count * 3 + major_count * 2 + minor_count * 1
        base_score = max(1, 10 - deduction)
        
        return {
            "structure_score": max(1, base_score - critical_count),
            "text_format_score": max(1, base_score - major_count),
            "table_format_score": max(1, base_score - minor_count // 2),
            "overall_score": base_score
        }
    
    def calculate_detailed_score(self, review_items: List[ReviewItem]) -> Dict[str, Any]:
        """计算详细评分"""
        # 初始分数
        scores = {
            "structure_score": 25,      # 结构规范性
            "text_format_score": 25,    # 文字格式
            "title_hierarchy_score": 20, # 标题层级
            "reference_format_score": 15, # 引用格式
            "language_expression_score": 15  # 语言表达
        }
        
        deductions = {
            "structure_score": 0,
            "text_format_score": 0,
            "title_hierarchy_score": 0,
            "reference_format_score": 0,
            "language_expression_score": 0
        }
        
        deduction_details = []
        
        # 根据问题类型和严重性扣分
        for item in review_items:
            severity_deduction = {"critical": 5, "major": 3, "minor": 1}.get(item.severity, 0)
            
            # 根据问题类别分配扣分
            if "结构" in item.category or "目录" in item.category:
                deductions["structure_score"] += severity_deduction
                deduction_details.append(f"结构规范性扣{severity_deduction}分: {item.description[:30]}...")
            elif "文字格式" in item.category or "字体" in item.category:
                deductions["text_format_score"] += severity_deduction
                deduction_details.append(f"文字格式扣{severity_deduction}分: {item.description[:30]}...")
            elif "标题" in item.category or "层级" in item.category:
                deductions["title_hierarchy_score"] += severity_deduction
                deduction_details.append(f"标题层级扣{severity_deduction}分: {item.description[:30]}...")
            elif "引用" in item.category or "注释" in item.category:
                deductions["reference_format_score"] += severity_deduction
                deduction_details.append(f"引用格式扣{severity_deduction}分: {item.description[:30]}...")
            elif "语言" in item.category or "表达" in item.category:
                deductions["language_expression_score"] += severity_deduction
                deduction_details.append(f"语言表达扣{severity_deduction}分: {item.description[:30]}...")
            else:
                # 默认扣文字格式分
                deductions["text_format_score"] += severity_deduction
                deduction_details.append(f"格式问题扣{severity_deduction}分: {item.description[:30]}...")
        
        # 计算最终分数
        final_scores = {}
        for key, base_score in scores.items():
            final_scores[key] = max(0, base_score - deductions[key])
        
        total_score = sum(final_scores.values())
        
        return {
            **final_scores,
            "total_score": total_score,
            "deduction_details": "; ".join(deduction_details) if deduction_details else "无扣分项"
        }